package com.weipu.common.facade.support.service.task;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.TimerTask;

import android.content.Intent;

import com.weipu.common.DXApplication;
import com.weipu.common.facade.support.service.TaskExecutor;
import com.weipu.common.facade.support.service.callback.ServiceTaskCallback;
import com.weipu.common.facade.support.service.callback.TaskDataBroadcastReceiver;

/**
 * 后台任务基础类，提供任务后台异步处理，数据请求与UI交互低耦合，功能如下：
 * 
 * 1、提供任务异步处理
 * 
 * 2、任务与UI操作相互独立
 * 
 * 3、支持任务回调：
 *    a、 广播通知方式(主线程操作)，需要注册动态广播接收数据)，详情见{@link com.weipu.common.facade.support.service.callback.TaskDataBroadcastReceiver}}
 *                            使用该方式前请设置setNeedBroadcast2UI-->true    
 *                                            
 *    b、 接口监听回调方式（注：异步线程操作），详见{@link com.weipu.common.facade.support.service.callback.ServiceTaskCallback}
 *                          使用以下函数添加监听addCallbackListener(ServiceTaskCallback<T> listener)
 *                          
 * @author Administrator
 *
 * @param <T>
 */
public abstract class BaseServiceTask<T extends Serializable> extends TimerTask implements Serializable
{
    
    protected static final String TAG = BaseServiceTask.class.getName();
    
    /**
     */
    private static final long serialVersionUID = -5632075686281070200L;
    
    /**
     * 任务对象参数 key
     * 可以传递的值为{@link BaseServiceTask}或者{@link ArrayList<BaseServiceTask}
     */
    public static final String TASK_DATA = "data_task_list";
    
    //    private boolean executeImmediate = false;//是佛立即执行任务,对多任务中立即并发执行
    //    public boolean isExecuteImmediate()
    //    {
    //        return executeImmediate;
    //    }
    //
    //    public void setExecuteImmediate(boolean executeImmediate)
    //    {
    //        this.executeImmediate = executeImmediate;
    //    }
    
    private boolean taskDone = false;//任务是否已经完成
    
    private boolean isNeedBroadcast2UI = false; //是否需要将数据广播到UI，请见TaskDataBroadcastReceiver
    
    private ArrayList<ServiceTaskCallback<T>> callbackListener;//数据回调对象
    
    private int whatForUICallback;//对于同一场景区分多个回调任务(类似 msg.what)
    
    private long delay;//延迟加载时长(毫秒数)
    
    private BaseServiceTask<?> nextTask;//当前任务的下一关联任务，任务链不需要有相同的泛型
    
    public static final int FROM_NOTICE_FEEDBACK =1;
    
    public void setNextTask(BaseServiceTask<?> nextTask)
    {
        this.nextTask = nextTask;
    }
    
    /**
     * 返回任务延迟加载(毫秒数)
     * @return  
     */
    public long getDelay()
    {
        return delay;
    }
    
    /**
     * 设置任务延迟加载(毫秒数)
     * @param delay
     */
    public void setDelay(long delay)
    {
        this.delay = delay;
    }
    
    /**
     * 任务是否已经完成
     * @return
     */
    public boolean isTaskDone()
    {
        return taskDone;
    }
    
    /**
     * 是否需要将数据广播到UI，请见TaskDataBroadcastReceiver
     * @param isNeedBroadcast2UI true: 数数据回调结束后后发送广， false: 不发送广播播
     */
    public void setNeedBroadcast2UI(boolean isNeedBroadcast2UI)
    {
        this.isNeedBroadcast2UI = isNeedBroadcast2UI;
    }
    
    /**
     * 对于同一场景区分多个回调任务(类似 msg.what)
     * @param whatForUICallback
     */
    public void setWhatForUICallback(int whatForUICallback)
    {
        this.whatForUICallback = whatForUICallback;
    }
    
    protected abstract boolean executeRequest();
    
    protected abstract T execute();
    
    public final void run()
    {
        boolean isExecuteNext = executeRequest();
        
        if (isExecuteNext)
        {
            T result = execute();
            
            executeResponse(result);
        }
    }
    
    /**
     * 添加任务回调监听，每次调用将新增一个监听实例
     * 数据回调时讲按照添加监听序列依次回调
     * @param listener 监听对象 {@link com.weipu.common.facade.support.service.callback.ServiceTaskCallback}
     */
    public void addCallbackListener(ServiceTaskCallback<T> listener)
    {
        if (null == callbackListener)
        {
            callbackListener = new ArrayList<ServiceTaskCallback<T>>();
        }
        callbackListener.add(listener);
    }
    
    //执行关联任务
    private void doNextTask()
    {
        if (null != nextTask)
        {
            TaskExecutor.doTaskInBackground(nextTask);
        }
    }
    
    /**
     * 任务执行结束，对外输出
     * 发送消息广播用于更新UI数据
     */
    protected void executeResponse(T result)
    {
        //广播任务回调
        if (isNeedBroadcast2UI)
        {
            Intent broad = new Intent(TaskDataBroadcastReceiver.ACTION_URL);
            broad.putExtra(TaskDataBroadcastReceiver.INTENT_OPTION_WHAT, whatForUICallback);
            broad.putExtra(TaskDataBroadcastReceiver.INTENT_DATA, result);
            DXApplication.getContext().sendBroadcast(broad);
        }
        
        //任务监听回调
        if (null != callbackListener && !callbackListener.isEmpty())
        {
            for (int i = 0; i < callbackListener.size(); i++)
            {
                callbackListener.get(i).response(result, whatForUICallback);
            }
        }
        
        //执行关联任务
        doNextTask();
        
        //任务执行完成
        taskDone = true;
    }
}
